﻿using System;
using System.Collections.Generic;
using System.Composition;
using System.Linq;
using System.Threading.Tasks;
using Unread.Business.Models;
using Unread.Business.Repositories.Interfaces;
using Unread.Business.Services.Interfaces;

namespace Unread.Business.Services
{
    [Export(typeof(IUnreadFeedItemLoader))]
    internal class UnreadFeedItemLoader : IUnreadFeedItemLoader
    {
        private readonly IFeedRepository _feedRepository;
        private readonly IFeedItemRepository _feedItemRepository;

        [ImportingConstructor]
        public UnreadFeedItemLoader(IFeedRepository feedRepository, IFeedItemRepository feedItemRepository)
        {
            if (feedRepository == null) throw new ArgumentNullException("feedRepository");
            if (feedItemRepository == null) throw new ArgumentNullException("syndicationClient");

            _feedRepository = feedRepository;
            _feedItemRepository = feedItemRepository;
        }

        public async Task<IEnumerable<FeedItem>> Load(Guid feedId)
        {
            var feed = await _feedRepository.GetById(feedId);
            if (feed == null)
                throw new InvalidOperationException(string.Format("Feed not found by id '{0}'", feedId));

            var feedItems = await _feedItemRepository.GetAll(feed.SyndicationUri);

            return GetUnreadItems(feedItems, feed.LastRead);
        }

        public async Task<int> LoadTotalCount()
        {
            var result = 0;

            var feeds = await _feedRepository.GetAll();
            if (!feeds.Any())
                return result;

            foreach (var feed in feeds)
            {
                var feedItems = await _feedItemRepository.GetAll(feed.SyndicationUri);
                var unread = feedItems.Where(i => i.PublishDate.ToLocalTime() > feed.LastRead).Count();
                result += unread;
            }

            return result;
        }

        public async Task<int> LoadTotalCount(Guid feedId)
        {
            var feedItems = await Load(feedId);

            return feedItems.Count();
        }

        private IEnumerable<FeedItem> GetUnreadItems(IEnumerable<FeedItem> feedItems, DateTime lastRead)
        {
            return feedItems.Where(i => i.PublishDate.ToLocalTime() > lastRead);
        }
    }
}